{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# 蒙特卡洛模拟\n",
    "\n",
    "import numpy as np\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.stats import norm\n",
    "from pandas_datareader import data\n",
    "\n",
    "#download Apple price data into DataFrame\n",
    "apple = data.DataReader('AAPL', 'yahoo',start='1/1/2000')\n",
    "\n",
    "#calculate the compound annual growth rate (CAGR) which \n",
    "#will give us our mean return input (mu) \n",
    "days = (apple.index[-1] - apple.index[0]).days\n",
    "cagr = ((((apple['Adj Close'][-1]) / apple['Adj Close'][1])) ** (365.0/days)) - 1\n",
    "print ('CAGR =',str(round(cagr,4)*100)+\"%\")\n",
    "mu = cagr\n",
    "\n",
    "#create a series of percentage returns and calculate \n",
    "#the annual volatility of returns\n",
    "apple['Returns'] = apple['Adj Close'].pct_change()\n",
    "vol = apple['Returns'].std()*math.sqrt(252)\n",
    "print (\"Annual Volatility =\",str(round(vol,4)*100)+\"%\")\n"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "#Define Variables\n",
    "S = apple['Adj Close'][-1] #starting stock price (i.e. last available real stock price)\n",
    "T = 252 #Number of trading days\n",
    "mu = 0.2309 #Return\n",
    "vol = 0.4259 #Volatility\n",
    "\n",
    "#create list of daily returns using random normal distribution\n",
    "daily_returns=np.random.normal((mu/T),vol/math.sqrt(T),T)+1\n",
    "\n",
    "#set starting price and create price series generated by above random daily returns\n",
    "price_list = [S]\n",
    "\n",
    "for x in daily_returns:\n",
    "    price_list.append(price_list[-1]*x)\n",
    "\n",
    "#Generate Plots - price series and histogram of daily returns\n",
    "plt.style.use('dark_background')\n",
    "plt.plot(price_list)\n",
    "plt.show()\n",
    "plt.hist(daily_returns-1, 100) #Note that we run the line plot and histogram separately, not simultaneously.\n",
    "plt.show()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "\n",
    "import numpy as np\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.stats import norm\n",
    "\n",
    "#Define Variables\n",
    "S = apple['Adj Close'][-1] #starting stock price (i.e. last available real stock price)\n",
    "T = 252 #Number of trading days\n",
    "mu = 0.2309 #Return\n",
    "vol = 0.4259 #Volatility\n",
    "\n",
    "#choose number of runs to simulate - I have chosen 1000\n",
    "for i in range(1000):\n",
    "    #create list of daily returns using random normal distribution\n",
    "    daily_returns=np.random.normal(mu/T,vol/math.sqrt(T),T)+1\n",
    "\n",
    "    #set starting price and create price series generated by above random daily returns\n",
    "    price_list = [S]\n",
    "\n",
    "    for x in daily_returns:\n",
    "        price_list.append(price_list[-1]*x)\n",
    "\n",
    "    #plot data from each individual run which we will plot at the end\n",
    "    plt.plot(price_list)\n",
    "\n",
    "#show the plot of multiple price series created above\n",
    "plt.show()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "\n",
    "import numpy as np\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.stats import norm\n",
    "\n",
    "#set up empty list to hold our ending values for each simulated price series\n",
    "result = []\n",
    "\n",
    "#Define Variables\n",
    "S = apple['Adj Close'][-1] #starting stock price (i.e. last available real stock price)\n",
    "T = 252 #Number of trading days\n",
    "mu = 0.2309 #Return\n",
    "vol = 0.4259 #Volatility\n",
    "\n",
    "#choose number of runs to simulate - I have chosen 10,000\n",
    "for i in range(10000):\n",
    "    #create list of daily returns using random normal distribution\n",
    "    daily_returns=np.random.normal(mu/T,vol/math.sqrt(T),T)+1\n",
    "\n",
    "    #set starting price and create price series generated by above random daily returns\n",
    "    price_list = [S]\n",
    "\n",
    "    for x in daily_returns:\n",
    "        price_list.append(price_list[-1]*x)\n",
    "\n",
    "    #plot data from each individual run which we will plot at the end\n",
    "    plt.plot(price_list)\n",
    "\n",
    "    #append the ending value of each simulated run to the empty list we created at the beginning\n",
    "    result.append(price_list[-1])\n",
    "\n",
    "#show the plot of multiple price series created above\n",
    "plt.show()\n",
    "\n",
    "#create histogram of ending stock values for our mutliple simulations\n",
    "plt.hist(result,bins=50)\n",
    "plt.show()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "\n",
    "#use numpy mean function to calculate the mean of the result\n",
    "print(round(np.mean(result),2))\n",
    "\n",
    "\n",
    "print(\"5% quantile =\",np.percentile(result,5))\n",
    "print(\"95% quantile =\",np.percentile(result,95))"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "\n",
    "plt.hist(result,bins=100)\n",
    "plt.axvline(np.percentile(result,5), color='r', linestyle='dashed', linewidth=2)\n",
    "plt.axvline(np.percentile(result,95), color='r', linestyle='dashed', linewidth=2)\n",
    "plt.show()"
   ],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.7.3 64-bit"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "interpreter": {
   "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}